#include "../libsf_flow/libsf_flow.h"
#include <iostream>

//y1=3x^2-6x+8
//y2=8x^2-20x-4

int main()
{
	flow_manager<double> manager;
	auto x_node = manager.add_node("x");
	auto y1_node = manager.add_node("y1");
	y1_node->add_node(x_node);
	y1_node->set_op([](std::map<std::string, double> d)->double
	{
		return 3 * d["x"] * d["x"] - 6 * d["x"] + 8;
	});
	auto y2_node = manager.add_node("y2");
	y2_node->add_node(x_node);
	y2_node->set_op([](std::map<std::string, double> d)->double
	{
		return 8 * d["x"] * d["x"] - 20 * d["x"] - 4;
	});

	auto y_node = manager.add_node("y");
	y_node->add_node(y1_node);
	y_node->add_node(y2_node);
	y_node->set_op([](std::map<std::string, double> d)->double
	{
		return d["y2"] - d["y1"];
	});

	x_node->set_value(9);
	std::cout << *y1_node << std::endl;
	std::cout << *y2_node << std::endl;

	manager.reset();

	x_node->set_value(2);
	std::cout << *y1_node << std::endl;
	std::cout << *y2_node << std::endl;
	std::cout << *y_node << std::endl;


	//  a
	//  b   a
	//  c       a
	//  d   b
	//  e

	std::map<std::string, double> data{ {"a",1},{"b",2},{"c",3},{"d",4},{"e",5} };
	single_flow_layer<double> layer_1;
	layer_1.set_values(data);

	single_flow_layer<double> layer_2;
	layer_2.set_child(&layer_1);
	layer_2.set_op([](std::map<std::string,double> d)->std::map<std::string,double>
	{
		std::map<std::string, double> ret;
		ret["a"] = d["a"] * d["b"] * d["c"] * d["d"] * d["e"];
		ret["b"] = d["a"] + d["b"] + d["c"] + d["d"] + d["e"];
		return ret;
	});

	single_flow_layer<double> layer_3;
	layer_3.set_child(&layer_2);
	layer_3.set_op([](std::map<std::string, double> d)->std::map<std::string, double>
	{
		std::map<std::string, double> ret;
		ret["a"] = d["a"] * d["b"];
		return ret;
	});

	std::cout << layer_2.get_values()["a"] << std::endl;
	std::cout << layer_2.get_values()["b"] << std::endl;
	std::cout << layer_3.get_values()["a"] << std::endl;
}